#include<stdio.h>      /*标准输入输出定义*/
#include<stdlib.h>     /*标准函数库定义*/
#include<unistd.h>     /*Unix标准函数定义*/
#include<sys/types.h>  /**/
#include<sys/stat.h>   /**/
#include<fcntl.h>      /*文件控制定义*/
#include<termios.h>    /*PPSIX终端控制定义*/
#include<errno.h>      /*错误号定义*/
#include<sys/time.h>
#include<pthread.h>
#include<string.h>
#include"../include/initM0.h"

pthread_mutex_t mutext,mutext1;


int sendQt;
int M0fd;

int set_serial(int MOfd,int nSpeed,int nBits,char nEvent,int nStop)
{
	struct termios newTtyusb,oldTtyusb;		//串口设置的结构体
	
	/*保存测试现有串口参数设置，在这里如果串口号等出错，会有相关的出错信息*/ 
	if( tcgetattr(M0fd,&oldTtyusb) != 0)
	{
		perror("Setupserial 1");
		return -1;
	}
	/*步骤一，设置字符大小*/ 
	newTtyusb.c_cflag |= (CLOCAL | CREAD);//CREAD开启串行数据接收，CLOCAL打开本地连接模式
	newTtyusb.c_cflag &= ~CSIZE; //设置数据位
	
	//数据位选择
	switch(nBits)
	{
		case 7:
			newTtyusb.c_cflag |= CS7;
			break;
		case 8:
			newTtyusb.c_cflag |= CS8;
			break;
	}
	printf("bit ok\n");
	
	//设置奇偶校验位
	switch(nEvent)
	{
		case 'o':
		case 'O':	//奇校验
			newTtyusb.c_cflag |= PARENB;	//开启奇偶校验
			newTtyusb.c_iflag |= (INPCK | ISTRIP);/*INPCK打开输入奇偶校验；ISTRIP去除字符的第八个比特  */
			newTtyusb.c_cflag |= PARODD; //启用奇校验（默认偶校验）
			break;
		case 'e':
		case 'E': //偶数 
			newTtyusb.c_iflag |= (INPCK | ISTRIP); 
			newTtyusb.c_cflag |= PARENB; 
			newTtyusb.c_cflag &= ~PARODD; 
			break;
		case 'n':
		case 'N':  //无奇偶校验位 
			newTtyusb.c_cflag &= ~PARENB; 
			break;
		default:
			break;
    } 
	printf("event ok\n");
	
	//设置波特率
	switch(nSpeed)
	{
		case 2400:
            cfsetispeed(&newTtyusb, B2400);
            cfsetospeed(&newTtyusb, B2400);
            break;
        case 4800:
            cfsetispeed(&newTtyusb, B4800);
            cfsetospeed(&newTtyusb, B4800);
            break;
        case 9600:
            cfsetispeed(&newTtyusb, B9600);
            cfsetospeed(&newTtyusb, B9600);
            break;
        case 115200:
            cfsetispeed(&newTtyusb, B115200);
            cfsetospeed(&newTtyusb, B115200);
            break;
        default:
            cfsetispeed(&newTtyusb, B9600);
            cfsetospeed(&newTtyusb, B9600);
            break;	
	}
	printf("speed ok\n");
	
	//设置停止位
	if(1 == nStop)/*设置停止位；若停止位为1，则清除CSTOPB，若停止位为2，则激活CSTOPB*/
	{
		newTtyusb.c_cflag &= ~CSTOPB; //默认1位停止位
	}
	else if(nStop == 2)
	{
		newTtyusb.c_cflag |= CSTOPB; //CSTOPB表示俩位停止位
	}
	/*设置最少字符和等待时间，对于接收字符和等待时间没有特别的要求时*/
	newTtyusb.c_cc[VTIME] = 0;/*非规范模式读取时的超时时间；*/
    newTtyusb.c_cc[VMIN]  = 0; /*非规范模式读取时的最小字符数*/
    tcflush(MOfd ,TCIFLUSH);	/*tcflush清空终端未完成的输入/输出请求及数据；TCIFLUSH表示清空正收到的数据，且不读取出来 */
	
	 /*激活配置使其生效*/
    if((tcsetattr( MOfd, TCSANOW,&newTtyusb))!=0)
    {
        perror("com set error");
        return -1;
    }
    return 0;
}


int initM0()
{
	M0fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY);
	if(-1 == M0fd)
	{
		perror("can't open serial port");
		//return M0_ERR;
	}
	set_serial(M0fd,115200,8,'N',1);//配置串口
    return M0fd;
}
void M0_recv(int M0fd,unsigned char recv_buf[36])
{
    while(1)
    {
        sleep(1);
	    int recv_len = read(M0fd,recv_buf,36);
	    printf("read len = %d\r\n" ,recv_len);
		if(recv_len > 0)
		{
			puts(recv_buf);
            break;
		}
        memset(recv_buf,0,sizeof(recv_buf));
    }
}


void M0_command(int M0fd,unsigned char *buf)
{
        //sleep(1);
        printf("--------------------------------\r\n");
        puts(buf);
        printf("--------------------------------\r\n");
	    int send_len = write(M0fd,buf,strlen(buf));
	    printf("send to M0 len = %d\r\n" ,strlen(buf));
		if(send_len > 0)
		{
	        printf("send_len = %d\r\n" ,send_len);
			puts(buf);
		}
}
